import java.io.FileWriter;
import java.io.IOException;

// 1. 自定义异常
class WorkHourException extends Exception {
    public WorkHourException(String msg) { super(msg); }
}

class SalaryException extends Exception {
    public SalaryException(String msg) { super(msg); }
}

// 2. 员工基类
abstract class Employee {
    // 公共属性
    protected String name;
    protected String empId;

    // 构造方法
    public Employee(String name, String empId) {
        this.name = name;
        this.empId = empId;
    }

    // 核心抽象方法：计算薪资
    public abstract double calculateSalary() throws WorkHourException, SalaryException;

    // 简化工资条生成
    public String generatePayroll() throws WorkHourException, SalaryException {
        double total = calculateSalary();
        return "工资条\n工号：" + empId + "\n姓名：" + name + "\n总薪资：" + total + "元\n";
    }
}

// 3. 普通员工子类
class RegularEmployee extends Employee {
    // 特有属性
    private double hourlyWage; // 小时工资
    private double workHours;  // 月工作时长

    public RegularEmployee(String name, String empId, double hourlyWage, double workHours) {
        super(name, empId);
        this.hourlyWage = hourlyWage;
        this.workHours = workHours;
    }

    // 薪资计算
    @Override
    public double calculateSalary() throws WorkHourException, SalaryException {
        if (hourlyWage <= 0) throw new SalaryException("小时工资不能为负");
        if (workHours <= 0 || workHours > 360) throw new WorkHourException("工作时长需在1-360小时");
        return Math.round(hourlyWage * workHours * 100) / 100.0; // 保留两位小数
    }

    // 工资条
    @Override
    public String generatePayroll() throws WorkHourException, SalaryException {
        return "【普通员工】\n" + super.generatePayroll() + "小时工资：" + hourlyWage + "元  工作时长：" + workHours + "小时\n";
    }
}

// 4. 管理人员子类
class Manager extends Employee {
    private double monthlySalary; // 月薪
    private double bonus;         // 奖金

    public Manager(String name, String empId, double monthlySalary, double bonus) {
        super(name, empId);
        this.monthlySalary = monthlySalary;
        this.bonus = bonus;
    }

    @Override
    public double calculateSalary() throws SalaryException {
        if (monthlySalary <= 0) throw new SalaryException("月薪不能为负");
        if (bonus < 0) throw new SalaryException("奖金不能为负");
        return Math.round((monthlySalary + bonus) * 100) / 100.0;
    }

    @Override
    public String generatePayroll() throws SalaryException, WorkHourException {
        return "【管理人员】\n" + super.generatePayroll() + "月薪：" + monthlySalary + "元  奖金：" + bonus + "元\n";
    }
}

// 5. 主类
public class SimpleSalarySystem {
    // 文件存储
    public static void saveToFile(String content) throws IOException {
        // 追加写入到项目根目录的"工资条.txt"
        try (FileWriter writer = new FileWriter("工资条.txt", true)) {
            writer.write(content + "-------------------------\n");
        }
    }

    // 主方法
    public static void main(String[] args) {
        // 创建2个员工实例
        Employee zhang = new RegularEmployee("张三", "REG001", 60, 176); // 60元/时，176小时
        Employee li = new Manager("李四", "MGR001", 20000, 8000);     // 月薪2万+奖金8千

        try {
            // 生成工资条+打印+存储
            String zhangPay = zhang.generatePayroll();
            String liPay = li.generatePayroll();

            System.out.println(zhangPay + liPay); // 控制台打印
            saveToFile(zhangPay);                 // 存储到文件
            saveToFile(liPay);
            System.out.println("工资条已存到「工资条.txt」");

        } catch (WorkHourException e) {
            System.out.println("工作时长错：" + e.getMessage());
        } catch (SalaryException e) {
            System.out.println("薪资错：" + e.getMessage());
        } catch (IOException e) {
            System.out.println("存文件错：" + e.getMessage());
        }
    }
}